package com.yanghui.dtracing.core.opentracing.sampler;

import com.yanghui.dtracing.core.opentracing.DTracerSpan;
import lombok.Setter;

import java.util.BitSet;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

public class TracerPercentageBasedSampler implements Sampler{

    @Setter
    private SamplerProperties samplerProperties;

    private final AtomicLong counter = new AtomicLong(0);

    private final BitSet sampleDecisions;

    public TracerPercentageBasedSampler(SamplerProperties samplerProperties){
        this.samplerProperties = samplerProperties;
        sampleDecisions = TracerPercentageBasedSampler.randomBitSet(100,this.samplerProperties.getPercentage(),new Random());
    }

    @Override
    public boolean sample(DTracerSpan request) {
        if (this.samplerProperties.getPercentage() == 0) {
            return false;
        } else if (this.samplerProperties.getPercentage() == 100) {
            return true;
        }
        long count = this.counter.getAndIncrement();
        return this.sampleDecisions.get((int) (count % 100));
    }

    public static BitSet randomBitSet(int size, int cardinality, Random rnd) {
        BitSet result = new BitSet(size);
        int[] chosen = new int[cardinality];
        int i;
        for (i = 0; i < cardinality; ++i) {
            chosen[i] = i;
            result.set(i);
        }
        for (; i < size; ++i) {
            int j = rnd.nextInt(i + 1);
            if (j < cardinality) {
                result.clear(chosen[j]);
                result.set(i);
                chosen[j] = i;
            }
        }
        return result;
    }

    @Override
    public void close() {
        //do something
    }
}
